local parser = require 'types.record.parser'
local mapper = require 'types.record.mapper'

local chars = { }
local bytes = { }
for i = 1, 48 do 
    chars[#chars+1] = ":B"
    bytes[#bytes+1] = 0
end 

local define = parser.new(chars, bytes)

local mt = {}
mt.__index = mt 

function mt:get(index)
    assert( index<=384, "索引超过上限" )
    local group = math.ceil(index / 8)
    local amount = index % 8
    if amount == 0 then 
        amount = 8
    end 
    return self[group] & (1 << (amount - 1)) ~= 0
end

function mt:set(index, value)
    assert( index<=384, "索引超过上限" )
    local group = math.ceil(index / 8)
    local amount = index % 8
    if amount == 0 then 
        amount = 8
    end 
    if value == true then
        self[group] = self[group] | (1 << (amount - 1))
    else
        self[group] = self[group] & ~(1 << (amount - 1))
    end
end


-- 读取服务器保存的布尔值
function ac.player.__index :get_stored_boolean(name)
	if not self.boolean_stores then
		return false 
	end
    local count = mapper.index("boolean", name)
    if not count then 
        log.error("没有声明的就进行使用的“boolean”类型存档", name)
        return false 
    end 
    local lcount = math.ceil(count / 384)
	local lindex = count % 384
    local lstore = self.boolean_stores[lcount]
	if lindex == 0 then 
		lindex = 384
	end 
	return lstore:get(lindex)
end 

-- 保存布尔值到服务器上
function ac.player.__index:store_boolean(name, value)
	if not self.boolean_stores then
		return false 
	end
    local count = mapper.index("boolean", name)
    if not count then 
        log.error("没有声明的就进行使用的“boolean”类型存档", name)
        return false 
    end 
    local lcount = math.ceil(count / 384)
	local lindex = count % 384
	if lindex == 0 then 
		lindex = 384
	end 
    local lname = ("boolean:%d"):format(lcount)
    local index = mapper.index('archive', lname)
    local sname = ("arc%d"):format(index)
    local lstore = self.boolean_stores[lcount]
	lstore:set(lindex, value and true or false)
	self:save_server_safe(sname, define:encode(lstore))
    return true
end 

local export = { }

-- 定义一个布尔类型的存档
function export.globals(name)
    mapper.define('boolean', name)
end 

function export.initialize()
    local amount = math.ceil((mapper.amount "boolean") / 384)
    for i = 1, 12 do 
        local player = ac.player(i)
        if player:is_online() then 
            player.boolean_stores = { }
            for j = 1, amount do 
                local lname = ("boolean:%d"):format(j)
                local index = mapper.define('archive', lname)
                local sname = ("arc%d"):format(index)
                player.boolean_stores[j] = setmetatable(define:decode( player:load_server(sname) ), mt)
            end 
        end 
    end 
end 

return export